package com.Angaliwa.Whiteboard {
	import com.Angaliwa.Core;
	import com.Angaliwa.DaisyChain;
	import com.Angaliwa.Settings;
	import com.Angaliwa.Whiteboard;
	
	import flash.events.SyncEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	public class Sync{
		/*
			Available daisyChain actions:
			- syncHandler
			- syncHandlerChanged
			- syncHandlerTimedTrigger
		*/
		public var daisyChain:DaisyChain = new DaisyChain(this),
				   settings:Settings = new Settings(this),
				   soHandler:* = Core.g('so'),
				   whiteboardsCollectionName:String = "whiteboards",
				   whiteboard:Whiteboard,
				   timer:Timer;
		
		private var previous:Object = [];
		
		public function init(soHandler:*=undefined, whiteboardsCollectionName:String=undefined):Sync{
			if(soHandler) this.soHandler = soHandler;
			if(whiteboardsCollectionName) this.whiteboardsCollectionName = whiteboardsCollectionName;
			
			settings.setDefaults({syncHandlerTimeoutTrigger: 1000});
			
			// Add a syncHandler to soHandler's daisyChain for user-
			// specific functions and checks.
			this.soHandler.daisyChain.a('syncHandler', syncHandler);
			
			return this;
		}
		
		public function syncHandler(e:SyncEvent):void{
			var changed:Boolean=false;
			
			for(var c:String in e.target.data[whiteboardsCollectionName]){
				var items:Array = e.target.data[whiteboardsCollectionName][c];
				
				if(!previous[c] || (previous[c] && previous[c].length < items.length)){
					var s:int = (previous[c]) ? previous[c].length : 0;
					
					for(var i:int=s; i < items.length; i++){
						var feature:String = items[i].feature;
						
						trace('[WHITEBOARD] [SYNC] [syncHandler] Updating item #'+i);
						
						if(whiteboard.features[feature].hasOwnProperty("sync"))
							whiteboard.features[feature].sync(c,items[i]);
					}
					
					previous[c] = new Array().concat(items);
					changed=true;
				}
			}
			
			// Daisychain handlers
			daisyChain.run('syncHandler');
			if(changed) daisyChain.run('syncHandlerChanged');
			
			if(timer) timer.stop();
			timer = new Timer(settings.get('syncHandlerTimeoutTrigger'),1);
			timer.addEventListener(TimerEvent.TIMER, function():void{
				daisyChain.run('syncHandlerTimedTrigger');
			});
			timer.start();
		}
		
		public function a(layer:String, d:Object):Boolean{
			var items:Object = [];
			
			// Check if there already are users present. If true,
			// add them to the newly created array. Also, we'll
			// run through them to see if we're not adding duplicate
			// users. Only the user's ID should be unique.
			if(soHandler.g(whiteboardsCollectionName) is Object){
				items = soHandler.g(whiteboardsCollectionName);
			}
			
			if(!items[layer])
				items[layer] = new Array();
			
			// Inject the user object into the users array.
			items[layer].push(d);
			
			// Push the newly created array back to the Shared 
			// Object handler.
			soHandler.a(whiteboardsCollectionName, items);
			
			// Return True to let the parent know the user was
			// successfully added.
			return true;
		}
	}
}